#ifndef __INCLUDED_EVEREST_ODBC_PARAMETER_H
#define __INCLUDED_EVEREST_ODBC_PARAMETER_H

#include <everest/basedef.h>
#include <sql.h>
#include <sqlext.h>


////////////////////////////////////////////////
// 0. Param in/out, other types:   Bind
// 1. Param in, string/binary:     Bind
// 2. Param out, string/binary:    Get
// 3. Param in/out, string/binary: Put/Get

BEGIN_NAMESPACE_EVEREST

namespace odbc
{
	enum ValueType
	{
		VT_NULL     = SQL_TYPE_NULL,
		VT_INT32    = SQL_INTEGER,
		VT_INT64    = SQL_BIGINT,
		VT_FLOAT    = SQL_REAL,
		VT_DOUBLE   = SQL_DOUBLE,
		VT_STRING   = SQL_CHAR,
		VT_BINARY   = SQL_BINARY,
		VT_DATETIME = SQL_TYPE_TIMESTAMP
	};

	class Statement;
	class Parameter
	{
		EVEREST_UNCOPIABLE(Parameter)
		friend class Statement;
		struct PData;
	public:
		static const int BUFFER_SIZE = 64;

	public:
		Parameter(SQLSMALLINT paramNum, ValueType type, SQLULEN size = 0, SQLSMALLINT scale = 0);
		virtual ~Parameter();

		void         setParamNum(SQLUSMALLINT num);
		SQLUSMALLINT getParamNum() const ;
		void         setDirection(SQLSMALLINT direction) ;
		SQLSMALLINT  getDirection() const ;
		ValueType    getType() const;
		SQLULEN      getSize() const;
		SQLSMALLINT  getScale() const;

		bool         getInt32(int& value) const;
		bool         getInt64(int64_t& value) const;
		bool         getFloat(float& value) const;
		bool         getDouble(double& value) const;
		bool         getString(String& value) const;
		bool         getBinary(ByteVector& value) const;
		bool         getDateTime(DateTime& value) const;
		bool         getTimestamp(Timestamp& value) const;

		bool         setInt32(int value);
		bool         setInt64(int64_t value);
		bool         setFloat(float value);
		bool         setDouble(double value);
		bool         setString(const String& value);
		bool         setString(const char *pszValue);
		bool         setBinary(const ByteVector& value);
		bool         setBinary(const void* pValue, size_t size);
		bool         setDateTime(const DateTime& value);
		bool         setTimestamp(const Timestamp& value);
		bool         setNull();

	protected:
		int          bind(SQLHSTMT hStmt);
		int          unbind();
		int          putData();
		void         setType(ValueType type);
		void         setSize(SQLULEN size);

	protected:
		SQLHSTMT     m_StmHandle;   ///< handle to the statment
		PData       *m_pData;       ///< private data structure
	};
	typedef CommonPtr<Parameter> ParameterPtr;

	struct ParamTypeMapEntry {
		ValueType    vt;
		SQLSMALLINT  sql_type;
		SQLSMALLINT  c_type;
	};

} // end of namespace odbc

END_NAMESPACE_EVEREST


#endif // __INCLUDED_EVEREST_ODBC_STATEMENT_H
